//============================================================================
// Copyright (C) 2010 Brett R. Jones
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

package com.roguetreasure.destroytheworld;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ConfigurationInfo;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.Vibrator;
import android.util.Log;

import android.view.Menu;
import android.view.MenuItem;
import android.widget.VideoView;
import android.widget.ViewFlipper;

public class DestroyWorldActivity extends Activity implements OnCompletionListener
{
    //==== libraries ===//
    static 
    { 
    	// load our c++ coded library with irrlicht and bullet etc
        System.loadLibrary("rt_destroytheworld");
    }
    
	private static final String LOG_TAG = "DestroyWorldActivity: ";

	private static final int INVISIBLE = (0x00000004);
	private static final int VISIBLE = (0x00000000);
	
    public static final int MENU_NEW_GAME = 1;
    public static final int MENU_PAUSE = 2;
    public static final int MENU_RESUME = 3;
    public static final int MENU_QUIT = 4;
    
	VxFileUtil 							m_oVxFileUtil = new VxFileUtil(); 
	private SensorMgr 					m_oSensorMgr;//Declare Sensor Manager class object
    public Vibrator 					m_oVibrator; 
    public 	VideoView 					m_oVideoView;  
    private DestroyWorldGLSurfaceView 	m_oGameView;
 	private ViewFlipper					m_oViewFlipper;

    PowerManager.WakeLock 	m_oWakeLock = null;
    public SoundMgr			m_oSoundMgr = null;
    public GameInterface	m_oGame = new GameInterface();
	private String			m_strCurVideoPath;
	private String			m_strLastVideoPath;
	public boolean			m_bShuttingDown = false;
	
	Timer 					m_oLoadSoundsTimer = null;  
	public Timer 			m_oStartupTimer = null;
	public boolean 			m_bSupportsEs2 = false;
     
    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {
    	menu.add(0, MENU_NEW_GAME, 0, "New Game");
    	menu.add(0, MENU_PAUSE, 0, "Pause");
    	menu.add(0, MENU_RESUME, 0, "Resume");
    	menu.add(0, MENU_QUIT, 0, "Quit");
    	return true;
    }
    
    //! Invoked when the user selects an item from the Menu.
    //! @param item the Menu entry which was selected     
    //! @return true if the Menu item was legit (and we consumed it), false otherwise     
    @Override    
    public boolean onOptionsItemSelected(MenuItem item) 
    {        
    	switch (item.getItemId()) 
    	{            
    	case MENU_NEW_GAME:   
    		m_oGame.GameRestart();
    		return true;            
    	case MENU_PAUSE:
    		m_oGame.GamePause();
    		return true;
    	case MENU_RESUME:
    		m_oGame.GameResume();
    		return true;
    	case MENU_QUIT:
    		Log.e(LOG_TAG, "DestroyWorldActivity:: Shutdown" );
    		Shutdown();
    		return true;
    	}
    	return false;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        //Log.e(LOG_TAG, "DestroyWorldActivity::onCreate stage 1" );
	    this.setContentView(R.layout.dtw_activity);
	    // setup view for media player
		m_oVideoView = (VideoView)this.findViewById(R.id.video_view);
		m_oVideoView.setVisibility(INVISIBLE);
		m_oVideoView.setFocusable(true);
		m_oVideoView.setBackgroundResource(0);
		m_oViewFlipper=(ViewFlipper)findViewById(R.id.details);
		

        // dont let phone sleep
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if( null != pm )
        {
        	//m_oWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "Destroy The World");
 //       	if( null != m_oWakeLock )
 //       	{
 //       		m_oWakeLock.acquire();
 //       	}
        }
        // keep phone in portrait mode
        this.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT );

        // setup to allow vibrate
    	m_oVibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
    	
    	
    	checkExternalMedia();
    }	
    
	//========================================================================
	public void checkExternalMedia() 
	{
		
		Log.d(LOG_TAG, "CheckExternalMedia ");
		if (false == m_oVxFileUtil.isExtenalStorageWritable()) 
		{
			Log.d(LOG_TAG, "CheckExternalMedia failed");
			Intent myIntent = new Intent( DestroyWorldActivity.this, ActivitySdCard.class );
			myIntent.putExtra("doanyway", false);
			DestroyWorldActivity.this.startActivityForResult( myIntent, Constants.ACTIVITY_SDCARD );
		} 
		else 
		{
			Log.d(LOG_TAG, "CheckExternalMedia success");
			beginStartupTask();
		}
	}
	
    //========================================================================
  	public void beginStartupTask() 
  	{
    	m_oStartupTimer = new Timer();
    	m_oStartupTimer.schedule( new startupTask(), 100 );			
  	}
  	
	//========================================================================	
	//tells activity to run on ui thread
	class startupTask extends TimerTask 
	{
        @Override
        public void run() 
        {
        	DestroyWorldActivity.this.runOnUiThread(new Runnable() {

                public void run() 
                {
                   	//ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                	//ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
                	
                	m_bSupportsEs2 = false; //configurationInfo.reqGlEsVersion >= 0x20000 || isProbablyEmulator();
            	 
               	    
            	    int nativeInitResult = m_oVxFileUtil.Startup( getResources(), m_bSupportsEs2 );
                    if( 0 != nativeInitResult )
                    {
                    	
                    }
                    
                    // copy game assets to sdcard for access from native code
                    
                    // make a list of sub directories of assets used by the game
                    List<String> listAssetSubDirs = new ArrayList<String>();

                    listAssetSubDirs.add("shaders");
                    listAssetSubDirs.add("gui");
                    listAssetSubDirs.add("levels");
                    listAssetSubDirs.add("meshes");
                    listAssetSubDirs.add("scenes");
                    listAssetSubDirs.add("textures");
                    
                    // Log.e(LOG_TAG, "DestroyWorldActivity::onCreate stage 2" );
                    
                    // copy game assets to sdcard for access from native code
                    String strSdcardPath = m_oVxFileUtil.m_strSdcardDir + "/dtw/";
                    try {
            	        m_oSoundMgr = new SoundMgr(DestroyWorldActivity.this);
            	        m_oSoundMgr.Startup();
            			m_oVxFileUtil.VxCreateDirectory( strSdcardPath );
            	        Iterator itSubdirs= listAssetSubDirs.iterator();
            	        while(itSubdirs.hasNext())
            	        {
            				// make asset sub directories
            	        	String strAssetSubDir = (String)itSubdirs.next();
            	        	String sdcardSubDir = strSdcardPath + strAssetSubDir;
            				m_oVxFileUtil.VxCreateDirectory( sdcardSubDir );
            		        // for each asset folder .. copy to sdcard folder
            		        AssetManager assetManager = getAssets();  
            		        String[] files = null;  
            		        try 
            		        {  
            		             files = assetManager.list(strAssetSubDir);  
            		        }
            		        catch (IOException e) 
            		        {  
            		             Log.e(LOG_TAG, e.getMessage());  
            		        }  
            		        int iFileCnt = files.length;
            		        for( int i = 0; i < iFileCnt; i++)
            		        {
            		        	// copy file from asset folder to sdcard in correct folder
            		        	String strJustFileName = files[i];
            		        	String strSrcFile = strAssetSubDir + "/" + strJustFileName;
            		        	String strDestFile = sdcardSubDir + "/" + strJustFileName;
            		        	
            		        	m_oVxFileUtil.VxCopyAsssetToSdcard( strSrcFile, 
            		        										strDestFile, true);
            		        	
            		        	if( 0 == m_oVxFileUtil.VxSdCardFileExists( strDestFile ) )
            		        	{
            		        		Log.e( LOG_TAG, "Asset File did not copy to " + strDestFile );
            		        	}
            		        }
            	        }
            	        Log.e(LOG_TAG, "DestroyWorldActivity::onCreate stage 3" );
            	        
            	        // initialize interface to native game code
            	        m_oGame.Startup( DestroyWorldActivity.this );
            	      
            	        //Log.e(LOG_TAG, "DestroyWorldActivity::onCreate stage 4" );
            	        
            			m_oGameView = (DestroyWorldGLSurfaceView) DestroyWorldActivity.this.findViewById(R.id.game_view);
            			//m_oGameView.SetParentActivity( this );
            			m_oGameView.Startup(DestroyWorldActivity.this);
            			
            			m_oViewFlipper.showNext();  
            	        
            	        Log.e(LOG_TAG, "DestroyWorldActivity::onCreate stage 5" );
            	        
            	        // setup sensor inputs
            	    	m_oSensorMgr = new SensorMgr( DestroyWorldActivity.this);
            	        
             		
            		} 
                    catch (IOException e) 
            		{
            			e.printStackTrace();
                        Log.e(LOG_TAG, e.getMessage());  
            		}
                   
                }}
        	);
        }
	}
	
	boolean isProbablyEmulator() 
    {
        return (Build.FINGERPRINT.startsWith("generic")
                        || Build.FINGERPRINT.startsWith("unknown")
                        || Build.MODEL.contains("google_sdk")
                        || Build.MODEL.contains("Emulator")
                        || Build.MODEL.contains("Android SDK built for x86"));
	}
   
    class LoadSoundsTask extends TimerTask 
    {   
    	public void run() 
    	{ 
    		m_oLoadSoundsTimer.cancel();
    		m_oSoundMgr.SfxPlay("choice2.ogg");
    	}
    }
    
    //------------------------------------------------------------------------
    // quit application and destroy
    //------------------------------------------------------------------------
    void Shutdown()
    {
    	m_bShuttingDown = true;
    	m_oGame.GameShutdown();
    	try 
    	{
			this.finish();
	    	System.exit(0);
		} 
    	catch (Throwable e) 
		{
			e.printStackTrace();
		}
    }
    
    //------------------------------------------------------------------------
    // application activity events
    //------------------------------------------------------------------------
    @Override
    protected void onPause() 
    {
        //Log.e(LOG_TAG, "DestroyWorldActivity::onPause" );
        //m_oGame.AppPause();
        super.onPause();
        //m_oGameView.onPause();
    	Shutdown();
    }

    @Override
    protected void onResume() 
    {
        //Log.e(LOG_TAG, "DestroyWorldActivity::onResume" );
        //m_oGame.AppResume();
        super.onResume();
        //m_oGameView.onResume();
		//m_oSensorMgr.onResume();
    }
    @Override
    protected void onStop() 
    {
    	super.onStop();
    	m_oSensorMgr.onStop();
    	// let phone sleep
 //   	if( null != m_oWakeLock )
 //   	{
 //   		m_oWakeLock.release();
 //   		m_oWakeLock = null;
 //   	}
   	}
    
    void GamePause()
    {
		//Log.d(LOG_TAG, "Game Pause");  
    	m_oGame.GamePause();
    }
    
    void GameResume()
    {
		//Log.d(LOG_TAG, "Game Resume");  
    	m_oGame.GameResume();
    }
    
	public void playMovie( String strMovie ) 
	{
		m_strCurVideoPath = strMovie;
		//only the gui thread can show movies.. therefore
        runOnUiThread(new Runnable() 
    	{
        	public void run() 
        	{
        		m_oGameView.setVisibility(INVISIBLE);
        		m_oVideoView.setVisibility(VISIBLE);
        		m_oVideoView.setOnCompletionListener((OnCompletionListener) DestroyWorldActivity.this);
        		//m_oGame.GamePause();
        		m_oVideoView.requestFocus();  

        		// open the raw resource, get the stream
                InputStream stream = getResources().openRawResource(R.raw.explodeplanet);
                //create a  temp file from stream and set path
                String strTmp;
        		try 
        		{
        			strTmp = createFileFromStream(stream);

        			if (strTmp == null || strTmp.length() == 0) 
        			{  
        				//Toast.makeText(this, "File URL/path is empty",  
        				//	 Toast.LENGTH_LONG).show();  
        			} 
        			else 
        			{  
        				// If the path has not changed, just start the media player  
        				if ((m_strCurVideoPath != null) && m_strCurVideoPath.equals(m_strLastVideoPath) && m_oVideoView != null) 
        				{  
        					m_oVideoView.start();  
        					m_oVideoView.requestFocus();  
        					return;  
        				}  
        				m_strLastVideoPath = m_strCurVideoPath;
        				m_oVideoView.setVideoPath(strTmp);  
        				m_oVideoView.start();  
        				m_oVideoView.requestFocus();  
        				//m_strTmpVidFile = strTmp;
        			}  
        		}
        		catch (Exception e) 
        		{  
        			Log.e(LOG_TAG, "playMovie: error " + e.getMessage(), e);  
        		} 
        		
        		//final long[] pattern = {100L, 100L}; 
        		
                Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); 
                if(vibrator != null)
                {
                	// 1. Vibrate for 1000 milliseconds   
                	long milliseconds = 5000;   
                	vibrator.vibrate(milliseconds);   
                	  
                	// 2. Vibrate in a Pattern with 500ms on, 500ms off for 5 times   
                	//long[] pattern = { 500, 300 };   
                	//vibrator.vibrate(pattern, 5);  
                	//vibrator.vibrate(pattern, -1);
                }
            }
    	});
	}
		
	// method to create a temp file from InputStream
    private String createFileFromStream(InputStream stream)
            throws IOException
    {
        if (stream == null)
        {
            throw new IOException("stream is null");
        }
        File temp = File.createTempFile("mediaplayertmp", "dat");
        String tempPath = temp.getAbsolutePath();
        FileOutputStream out = new FileOutputStream(temp);
        byte buf[] = new byte[128];
        do
        {
            int numread = stream.read(buf);
            if (numread <= 0)
            {
                break;
            }
            out.write(buf, 0, numread);
        }
        while (true);
        out.close();
        
        try
        {
            stream.close();
        }
        catch (IOException ex)
        {
            Log.e(LOG_TAG, "playMovie error: " + ex.getMessage(), ex);
        }
        return tempPath;
    }
    
	public void onCompletion(MediaPlayer arg0) 
	{
        //Log.e(LOG_TAG, "playMovie: movie completed " );
		m_oVideoView.setVisibility(INVISIBLE);
		m_oGameView.setVisibility(VISIBLE);
	}

	//========================================================================
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) 
	{
		super.onActivityResult(requestCode, resultCode, data);
		Log.d(LOG_TAG, "onActivityResult result code " + resultCode);
		switch (requestCode) 
		{
		case Constants.ACTIVITY_SDCARD:
			Log.d(LOG_TAG, "onActivityResult ACTIVITY_SDCARD");
			if (resultCode == Activity.RESULT_OK) 
			{
				beginStartupTask();
			}
			else 
			{
				Log.d(LOG_TAG,
						"onActivityResult ACTIVITY_SDCARD calling finish");
				finish();
			}
			break;
	
		}	
	}

}

